//
// Created by Administrator on 2022/10/10.
//
#include "http_net_config.h"
void _close_http(req_header_t *header) {
    if(ISNULL(header->hset) || ISNULL(header->fds))
        return;
    http_free(header->fds->fdc);
    destroy_lock(&header->fds->lock);
    http_free(header->fds);
    _clear_req_head(header->attr);
}
/**
 * http 的请求头处理
 */
void http_request_header_handler(req_header_t * header) {
    struct requestContext request = {
        header->fd,
        NULL,
        header->attr->Method,
        header->attr->path,
        NULL,
        header->head,
        header->body,
        header->fds,
        header->hset
    };
#if defined(FILE_SYSTEM_EVENT)
    if(0){
        request.home = dtsnew("/home/");
        file_system_app(&request, _file_before_response_callback, _file_running_response_callback, _file_after_response_callback);
        dtsfree(request.home);
    }
    if(1) {
        port_system_app(&request, _port_before_response_callback, _port_running_response_callback, _port_after_response_callback);
    }
#endif
}
void _request_http_handler(req_header_t *header) {
    http_request_header_handler(header);
}
// 请求头处理程序
void requst_control(req_header_t *header){
    _request_http_handler(header);
}

static int _request_recv_do(req_header_t *header, dts *head){
    int index;
    if(!header->head) {
        if(!*head)
            *head = dtsempty();
        header->head_len += header->buf_len;
        *head = dtscatlen(*head, header->buf, header->buf_len);
        if((index = indexof(*head, HEAD_TAIL)) > -1) {
            (*head)[index + strlen(HEAD_TAIL)] = '\0';
            int real_h_len_ = (index + strlen(HEAD_TAIL));
            header->head = *head;
            _before_request_callback(header);
            int buf_tail_len = header->head_len - real_h_len_;
            int buf_tail_idx = header->buf_len - buf_tail_len;
            strcpyfromlen(header->buf, header->buf, buf_tail_idx, 0, buf_tail_len);
            header->buf[buf_tail_len] = '\0';
            header->buf_len = buf_tail_len;
            _running_request_callback(header);
        }
    } else {
        _running_request_callback(header);
    }
    if(header->req_stream.read_end) {
        _after_request_callback(header);
    }
}
static void _request_cycle(void *args, thread_task_args_t *args_t) {
    http_inner_request_before_facade_t *hirqbft = (http_inner_request_before_facade_t *)args;

    struct http_fd_s *fds = hirqbft->fds;
    struct http_socket_event_s *hset = hirqbft->hset;
    http_free_null(&hirqbft);

    struct request_head_attr_s attr = { NULL };
    req_header_t header = { fds->fd, NULL, NULL, 0, {0}, 0, &attr, fds, hset
                            , {0,0,0,0,0
    } };
    init_req_attr(&attr);
    dts headstr = NULL;
    do{
        mutex_lock(&fds->lock);
        header.buf_len = getData(hset->logs, header.fd, header.buf, (sizeof header.buf) - 1);
        mutex_unlock(&fds->lock);
        //如果客户端主动断开连接，会进行四次挥手，会出发一个信号，此时相应的套接字会有数据返回，告诉select，我的客户断开了，你返回-1
        if (header.buf_len == 0) {
            _close_http(&header);                   // 任务结束
            break;
        } else if (header.buf_len < 0) {
            if(errno == EAGAIN || errno == EWOULDBLOCK){
                continue;
            } else if (errno == ECONNRESET || errno == ECONNREFUSED) {
                _close_http(&header);
                break;
            } else if(errno == ECONNABORTED) {
                _close_http(&header);
                break;
            } else if (errno == EINTR) {
                _close_http(&header);
                break;
            } else {
                _close_http(&header);
                break;
            }
        } else {
            if(header.buf_len < sizeof header.buf)
                memset(&header.buf[header.buf_len],'\0',1);
            _request_recv_do(&header, &headstr);
            if(header.req_stream.read_end) {
                requst_control(&header);
                _close_http(&header);
                break;
            }
        }
    } while (1);
}

void ___socket_r_callback(struct http_socket_event_s *hset, int fd) {
    http_inner_request_before_facade_t *hirqbft = (http_inner_request_before_facade_t *)http_malloc(sizeof(http_inner_request_before_facade_t));
    hirqbft->hset = hset;

    char *fdc = (char *) http_calloc(sizeof(char) * INT32_LEN);
    memset(fdc, 0, sizeof(fdc));
    http_sprintf(fdc, "%d", fd);

    struct http_fd_s *fds = (struct http_fd_s *) http_malloc(sizeof(struct http_fd_s));
    init_lock(&fds->lock);
    fds->fd = fd;
    fds->fdc = fdc;
    fds->state = FD_USE;
    hirqbft->fds = fds;
    Thread_Task_Post(hset->hgdc->tpt, _request_cycle, hirqbft);
}
void __socket_w_callback(struct http_socket_event_s *hset, int fd){
    close(fd);
}

void _before_request_callback(req_header_t *header) {
    _req_analysis_head(header);
}
void _running_request_callback(req_header_t *header) {
    _req_analysis_body(header);
}
void _after_request_callback(req_header_t *header) {
}